package com.wandian.texas;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;

import com.wandian.util.Log;

/**
 * @author long
 * @Create 2012-10-3 下午4:02:55
 * @QQ 108232706
 * @version 1.0
 */
public class DataPacket {

	public short cmdId = -1;
	// public byte[] bytes;
	public ByteBuffer byteBuffer;
	public int length;
	private final Charset charset = Charset.forName("UTF-8");

	// public DataPacket(short _cmdid) {
	// this.cmdId = _cmdid;
	// }

	/**
	 * 默认构造，1k的包
	 */
	// public DataPacket() {
	// byteBuffer = ByteBuffer.allocate(1024);// 如何分配的问题
	// byteBuffer.order(ByteOrder.LITTLE_ENDIAN);// 未初始化会异常
	// }

	public DataPacket(int size) {
		length = size;
		byteBuffer = ByteBuffer.allocate(length);
		byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
	}

	/**
	 * 根据字节数组来初始化ByteBuffer
	 * 
	 * @param bytes
	 */
	public DataPacket(short cmdId, byte[] bytes) {
		this.cmdId = cmdId;
		length = bytes.length;
		byteBuffer = ByteBuffer.wrap(bytes);
		byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
	}

	public DataPacket(ByteBuffer buffer) {
		byteBuffer = buffer;
		length = buffer.limit();
	}

	// ================================处理显示，打印，所有的操作不改变position===========

	/**
	 * 将数据以16进制展现
	 * 
	 * @return
	 */
	public String byteToHex() {
		return "";
		/*if (byteBuffer == null)
			return "";
		StringBuilder tempStr = new StringBuilder("[");
		int oldpositon = byteBuffer.position();
		String value;
		while (byteBuffer.remaining() > 0) {
			value = Integer.toHexString(byteBuffer.get() & 0xFF);
			tempStr.append(value.length() > 1 ? value : String.format("0%s", value)).append(",");
		}
		tempStr.append("]");
		byteBuffer.position(oldpositon);
		return tempStr.toString().toUpperCase();*/
	}

	/**
	 * 每字节的数值
	 * 
	 * @return
	 */
	public String byteToString() {
		if (byteBuffer == null)
			return "";
		StringBuilder tempStr = new StringBuilder("[");
		int oldpositon = byteBuffer.position();
		while (byteBuffer.remaining() > 0) {
			tempStr.append(byteBuffer.get()).append(",");
		}
		tempStr.append("]");
		byteBuffer.position(oldpositon);
		return tempStr.toString();
	}

	public String decodeToString() {
		if (byteBuffer == null)
			return "";
		return charset.decode(byteBuffer).toString();
	}

	// 写操作

	/**
	 * 根据字节数组初始化
	 * 
	 * @param bytes
	 */
	// public ByteBuffer wrap(byte[] bytes) {
	// byteBuffer = ByteBuffer.wrap(bytes);
	// byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
	// return byteBuffer;
	// }

	// public ByteBuffer wrap(String msg) {
	// byteBuffer = charset.encode(msg).slice();
	// // byteBuffer = ByteBuffer.wrap(bytes);
	// byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
	// return byteBuffer;
	// }

	// 以下写需要注意位置
	public void writeBegin() {
		if (byteBuffer == null) {
			byteBuffer = ByteBuffer.allocate(1024);
			byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
		} else {
			byteBuffer.clear();
		}
	}

	// public void writeBegin(int size) {
	// byteBuffer = ByteBuffer.allocate(size);
	// byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
	// }

	public void writeByte(byte value) {
		byteBuffer.put(value);
	}

	public void writeBytes(byte[] bytes) {
		if (bytes!=null&&byteBuffer.remaining() >= bytes.length) {
			byteBuffer.putInt(bytes.length);
			byteBuffer.put(bytes);
		} else {
			byteBuffer.putInt(0);
		}

	}

	public void putBytes(byte[] bytes) {
		byteBuffer.put(bytes);
	}

	public void writeShort(Short value) {
		byteBuffer.putShort(value);
	}

	public void writeInt(int value) {
		byteBuffer.putInt(value);
	}

	public void writeFloat(float value) {
		byteBuffer.putFloat(value);
	}

	public void writeString(String msg) {
		if (msg == null)
			msg = "";
		ByteBuffer temp = charset.encode(msg);// ProtoBufUtil.getInstance().encode(msg,
												// true);
		byteBuffer.putInt(temp.remaining() + 1);// 写入长度
		byteBuffer.put(temp);
		byteBuffer.put((byte) 0);// 结尾标识符
	}

	public void writeEnd() {
		byteBuffer.flip();
	}

	// 读取操作

	public char readChar() {
		return byteBuffer.getChar();
	}

	public byte readByte() {
		return byteBuffer.get();
	}

	public void readBytes(byte[] dst, int offset, int length) {
		byteBuffer.get(dst, offset, length);
	}

	// 为了不new内存,直接使用byteBuffer
	// public byte[] readBytes() {
	// int len = byteBuffer.getInt();
	//
	// }

	public float readFloat() {
		return byteBuffer.getFloat();
	}

	public long readLong() {
		return byteBuffer.getLong();
	}

	public double readDouble() {
		return byteBuffer.getFloat();
	}

	public int readInt() {
		return byteBuffer.getInt();
	}

	public short readShort() {
		return byteBuffer.getShort();
	}

	public String readString() {
		// length|bytes
		String msgString = "";
		int length = byteBuffer.getInt();
		if (byteBuffer.remaining() >= length) {
			int oldlimit = byteBuffer.limit();
			int oldPosition = byteBuffer.position();
			byteBuffer.limit(byteBuffer.position() + length - 1);
			if (length > 0) {
				msgString = charset.decode(byteBuffer).toString();// ProtoBufUtil.getInstance().decode(byteBuffer,
																	// true);
			}
			byteBuffer.limit(oldlimit);
			byteBuffer.position(oldPosition + length);
		}
		return msgString;
	}

	public ByteBuffer pack() {
		int l = length();
		ByteBuffer byteBufferer = ByteBuffer.allocate(l);
		if (position() > 0) {
			flip();
		}
		byteBufferer.put(array(), 0, l);
		byteBufferer.flip();
		return byteBufferer;
	}

	public byte[] array() {
		return byteBuffer.array();
	}

	public int position() {
		return byteBuffer.position();
	}

	public void position(int newPosition) {
		byteBuffer.position(newPosition);
	}

	public int remaining() {
		return byteBuffer.remaining();
	}

	public int limit() {
		return byteBuffer.limit();
	}

	public void flip() {
		byteBuffer.flip();
	}

	public void clear() {
		byteBuffer.clear();
		length = 0;
	}

	/**
	 * 
	 * @return
	 */
	public int length() {
		return length - byteBuffer.remaining();
	}

	/**
	 * 
	 * 
	 * @return
	 */
	public int totalSize() {
		return length;
	}

	public void outInfo(byte[] bytes) {
		for (int i = 0; i < bytes.length; i++) {
			Log.debug("---------" + bytes[i]);
		}
	}
}
